package controller;

import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.imgscalr.Scalr;
import org.json.JSONArray;
import org.json.JSONObject;

import com.google.gson.Gson;

import definePresent.model.PresentBean;
import defineProduct.model.ItemBean;
import model.DatabaseException;
import model.User;
import model.Utilities;

@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
        
    /**
        * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
        * 
        */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	System.out.println("in Do GET");
        HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		if(user==null || !user.getAccountType().equals("S")){
			response.sendRedirect("Login.html");
		}
    	ItemBean item = (ItemBean) session.getAttribute("item");
        PresentBean present = (PresentBean) session.getAttribute("present");
        String define = (String) session.getAttribute("define");
        long colorId = 0;
        if(define.equals("product")){
        	colorId = (long) session.getAttribute("colorId");
        }
    	
        if (request.getParameter("getfile") != null && !request.getParameter("getfile").isEmpty()) {
            File file = new File(request.getServletContext().getRealPath("/")+"images/"+request.getParameter("getfile"));
            if (file.exists()) {
                int bytes = 0;
                ServletOutputStream op = response.getOutputStream();

                response.setContentType(getMimeType(file));
                response.setContentLength((int) file.length());
                response.setHeader( "Content-Disposition", "inline; filename=\"" + file.getName() + "\"" );

                byte[] bbuf = new byte[1024];
                DataInputStream in = new DataInputStream(new FileInputStream(file));

                while ((in != null) && ((bytes = in.read(bbuf)) != -1)) {
                    op.write(bbuf, 0, bytes);
                }

                in.close();
                op.flush();
                op.close();
            }
        } else if (request.getParameter("delfile") != null && !request.getParameter("delfile").isEmpty()) {
            File file = new File(request.getServletContext().getRealPath("/")+"images/"+ request.getParameter("delfile"));
            if(define.equals("product")){
            	item.removeColorFigurePath(colorId, "images/"+request.getParameter("delfile"));
            }else{
            	present.setFigure(null);
            }
            
//            Gson gson = new Gson();
//            System.out.println("After deleting:"+ gson.toJson(item));
//            System.out.println("Get: file to delete:" + file.getAbsolutePath());
            if (file.exists()) {
                file.delete(); // TODO:check and report success
            } 
        } else if (request.getParameter("getthumb") != null && !request.getParameter("getthumb").isEmpty()) {
            File file = new File(request.getServletContext().getRealPath("/")+"images/"+request.getParameter("getthumb"));
                if (file.exists()) {
                    System.out.println(file.getAbsolutePath());
                    String mimetype = getMimeType(file);
                    if (mimetype.endsWith("png") || mimetype.endsWith("jpeg")|| mimetype.endsWith("jpg") || mimetype.endsWith("gif")) {
                        BufferedImage im = ImageIO.read(file);
                        if (im != null) {
                            BufferedImage thumb = Scalr.resize(im, 75); 
                            ByteArrayOutputStream os = new ByteArrayOutputStream();
                            if (mimetype.endsWith("png")) {
                                ImageIO.write(thumb, "PNG" , os);
                                response.setContentType("image/png");
                            } else if (mimetype.endsWith("jpeg")) {
                                ImageIO.write(thumb, "jpg" , os);
                                response.setContentType("image/jpeg");
                            } else if (mimetype.endsWith("jpg")) {
                                ImageIO.write(thumb, "jpg" , os);
                                response.setContentType("image/jpeg");
                            } else {
                                ImageIO.write(thumb, "GIF" , os);
                                response.setContentType("image/gif");
                            }
                            ServletOutputStream srvos = response.getOutputStream();
                            response.setContentLength(os.size());
                            response.setHeader( "Content-Disposition", "inline; filename=\"" + file.getName() + "\"" );
                            os.writeTo(srvos);
                            srvos.flush();
                            srvos.close();
                        }
                    }
            } // TODO: check and report success
        } else {
            PrintWriter writer = response.getWriter();
            writer.write("call POST with multipart form data");
        }
    }
    
    /**
        * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
        * 
        */
    @SuppressWarnings("unchecked")
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		if(user==null || !user.getAccountType().equals("S")){
			response.sendRedirect("Login.html");
		}
    	System.out.println("Post in UploadServlet");
        if (!ServletFileUpload.isMultipartContent(request)) {
            throw new IllegalArgumentException("Request is not multipart, please 'multipart/form-data' enctype for your form.");
        }
        long uin =0;
     
        ItemBean item = (ItemBean) session.getAttribute("item");
        PresentBean present = (PresentBean) session.getAttribute("present");
        String define = (String) session.getAttribute("define");
        ServletFileUpload uploadHandler = new ServletFileUpload(new DiskFileItemFactory());
        PrintWriter writer = response.getWriter();
        response.setContentType("application/json");
        JSONArray json = new JSONArray();
        String suffix;
        String fileName;
        long colorId = 0;
        if(define.equals("product")){
        	colorId = (long)session.getAttribute("colorId");
        }
        try {
            List<FileItem> items = uploadHandler.parseRequest(request);
            for (FileItem fileItem : items) {
                if (!fileItem.isFormField()) {
                    //get unique number to insure file names are different!
            		try {
            			uin = Utilities.getUniqueNumber();
            		} catch (DatabaseException e1) {
            			response.sendRedirect("TechnicalDifficulties.html");
            		}
            		suffix = getSuffix(fileItem.getName());
            		fileName = "figure_"+uin+"."+suffix;
            		File path = new File(request.getServletContext().getRealPath("/"),"images");
            		System.out.println(path.toString());
                    File file = new File(path,fileName);
                    fileItem.write(file);
                    if(define.equals("product")){
                    	 item.addColorFigurePath(colorId, "images/"+fileName);
                         session.setAttribute("item", item);
                    }else{
                    	present.setFigure("images/"+fileName);
                    	session.setAttribute("present", present);
                    }
               
                    JSONObject jsono = new JSONObject();
                    jsono.put("name", fileItem.getName());
                    jsono.put("size", fileItem.getSize());
                    jsono.put("url", "/Store/UploadServlet?getfile=" + fileName);
                    jsono.put("thumbnail_url", "/Store/UploadServlet?getthumb=" + fileName);
                    jsono.put("delete_url", "/Store/UploadServlet?delfile=" + fileName);
                    jsono.put("delete_type", "GET");
                    json.put(jsono);
//                    System.out.println(json.toString());
//                    System.out.println("item.getname(): "+fileItem.getName());
                }
            }
        } catch (FileUploadException e) {
                throw new RuntimeException(e);
        } catch (Exception e) {
                throw new RuntimeException(e);
        } finally {
            writer.write(json.toString());
            writer.close();
        }

    }

    private String getMimeType(File file) {
        String mimetype = "";
        if (file.exists()) {
            if (getSuffix(file.getName()).equalsIgnoreCase("png")) {
                mimetype = "image/png";
            }else if(getSuffix(file.getName()).equalsIgnoreCase("jpg")){
                mimetype = "image/jpg";
            }else if(getSuffix(file.getName()).equalsIgnoreCase("jpeg")){
                mimetype = "image/jpeg";
            }else if(getSuffix(file.getName()).equalsIgnoreCase("gif")){
                mimetype = "image/gif";
            }else {
                javax.activation.MimetypesFileTypeMap mtMap = new javax.activation.MimetypesFileTypeMap();
                mimetype  = mtMap.getContentType(file);
            }
        }
        return mimetype;
    }



    private String getSuffix(String filename) {
        String suffix = "";
        int pos = filename.lastIndexOf('.');
        if (pos > 0 && pos < filename.length() - 1) {
            suffix = filename.substring(pos + 1);
        }
        return suffix;
    }
}